package com.jzhao.gper.interpreter;

import java.util.Stack;

public class JZCalculator {

    private Stack<ICalculationExpression> stack = new Stack<ICalculationExpression>();


    public JZCalculator(String expression) {
        System.out.println(expression);
        this.parse(expression);
    }

    private void parse(String expression) {
        String[]  elements= expression.split(" ");

        for (int i = 0; i<elements.length;i++) {
            String element = elements[i];
            //如果是括号
            if(OptUtil.isBracket(element)){
                ICalculationExpression top = stack.peek();
                String[] bracketElements = OptUtil.getElements(i,elements);
                ICalculationExpression bracket = new BracketExpression(bracketElements);
                stack.push(bracket);
                i = i + bracketElements.length;
            }
            //如果是运算符
            else if(OptUtil.isSymbol(element)){
                ICalculationExpression left = stack.pop();

                if(!OptUtil.isBracket(elements[i+1])){
                    ICalculationExpression right = new NumExpression(Integer.valueOf(elements[++i]));

                    //创建运算符表达式
                    ICalculationExpression  operationExpression= OptUtil.createOperationExpression(element,left,right);

                    stack.push(operationExpression);
                } else {
                    String[] bracketElements = OptUtil.getElements(i+1,elements);
                    ICalculationExpression right = new BracketExpression(bracketElements);

                    //创建运算符表达式
                    ICalculationExpression  operationExpression= OptUtil.createOperationExpression(element,left,right);
                    stack.push(operationExpression);
                    i = i + bracketElements.length;
                }
            }
            //不是运算符，直接入栈
            else {
                stack.push(new NumExpression(Integer.valueOf(element)));
            }
        }
    }

    public int calculate() {
        return this.stack.pop().interpret();
    }
}
